#pragma once
#include "core.h"

#if defined(_MSC_VER)  // Visual C++
#define QB_FUNC __FUNCSIG__
#elif (defined(__GNUC__))  // GCC
#define QB_FUNC __PRETTY_FUNCTION__
#elif (defined(__clang__) && (__clang__ == 1))  // Clang++
#define QB_FUNC __PRETTY_FUNCTION__
#else
#if defined(__func__)
#define QB_FUNC __func__
#else
#define QB_FUNC ""
#endif  // defined(__func__)
#endif  // defined(_MSC_VER)

enum class LogLevel { Trace, Debug, Info, Warning, Error, Fatal };

S_CORE_EXPORT void qb_log(LogLevel level, const char* file,
                          const char* function, int line, const char* msgfmt,
                          ...);

#define log_trace(format, ...) \
  qb_log(LogLevel::Trace, __FILE__, QB_FUNC, __LINE__, format, ##__VA_ARGS__)
#define log_debug(format, ...) \
  qb_log(LogLevel::Debug, __FILE__, QB_FUNC, __LINE__, format, ##__VA_ARGS__)
#define log_info(format, ...) \
  qb_log(LogLevel::Info, __FILE__, QB_FUNC, __LINE__, format, ##__VA_ARGS__)
#define log_warning(format, ...) \
  qb_log(LogLevel::Warning, __FILE__, QB_FUNC, __LINE__, format, ##__VA_ARGS__)
#define log_error(format, ...) \
  qb_log(LogLevel::Error, __FILE__, QB_FUNC, __LINE__, format, ##__VA_ARGS__)
#define log_fatal(format, ...) \
  qb_log(LogLevel::Fatal, __FILE__, QB_FUNC, __LINE__, format, ##__VA_ARGS__)
#define log_begin() \
  qb_log(LogLevel::Debug, __FILE__, QB_FUNC, __LINE__, "begin!")
#define log_end() qb_log(LogLevel::Debug, __FILE__, QB_FUNC, __LINE__, "end!")
